package controllers

import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}

import java.io.File
import javax.inject.Inject
import scala.concurrent.ExecutionContext.Implicits.global
import dao._
import tool.{FormTool, Tool}
import utils.Utils
import implicits.Implicits._
import shared.pojo.Browse.GetFileData
import ujson.play.PlayJson
import upickle.default._

import java.nio.file.Files
import scala.collection.immutable.SeqMap

/** Created by yz on 11/5/2020
  */
class BrowseController @Inject() (cc: ControllerComponents)(
    implicit val prokaryoteDao: ProkaryoteDao,
    implicit val bioSampleDao: BioSampleDao,
    implicit val assemblyDao: AssemblyDao
) extends AbstractController(cc) {

  def toIndex = Action { implicit request =>
    Ok(views.html.browse.index())
  }

  def getAllProkaryote = Action.async { implicit request =>
    val f = prokaryoteDao.selectAll
    f.map { x =>
      val array = Utils.getArrayByTs(x)
      Ok(Json.toJson(array))
    }
  }

  def detailInfoBefore = Action { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    Ok(views.html.browse.detailInfo(data.id))
  }

  def getBioSampleById = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    bioSampleDao.select(data.id).map { x =>
      Ok(writeJs(x))
    }
  }

  def getAssemblyById = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    prokaryoteDao
      .selectByBioSample(data.id)
      .flatMap { row =>
        assemblyDao.select(row.assembly)
      }
      .map { x =>
        Ok(writeJs(x))
      }
  }

  def getMummerFileData = Action { implicit request =>
    val data = Tool.transformRq.transform(reader[GetFileData.Request])
    val file = new File(Tool.mummerDir, s"${data.id}/${data.fileName}")
    val (map, array) = if (file.exists()) {
      val lines = file.lines.take(10001).map(_.mySplit("\t"))
      Utils.getInfoByLines(lines)
    } else {
      (SeqMap[String, String](), List.empty)
    }
    val response = GetFileData.Response(map = map, array = array)
    Ok(writeJs(response))
  }

  def getMummerImage = Action { implicit request =>
    val ifModifiedSinceStr = request.headers.get(IF_MODIFIED_SINCE)
    val data = FormTool.fileNameForm.bindFromRequest().get
    val file = new File(Tool.mummerDir, data.fileName)
    val lastModifiedStr = file.lastModified().toString
    val MimeType = "image/png"
    val byteArray = Files.readAllBytes(file.toPath)
    if (ifModifiedSinceStr.isDefined && ifModifiedSinceStr.get == lastModifiedStr) {
      NotModified
    } else {
      Ok(byteArray).as(MimeType).withHeaders(LAST_MODIFIED -> file.lastModified().toString)
    }
  }

  def downloadMummerFile = Action { implicit request =>
    val data = FormTool.fileNameForm.bindFromRequest().get
    val file = new File(Tool.mummerDir, data.fileName)
    Ok.sendFile(file)
      .withHeaders(
        CONTENT_DISPOSITION -> Tool.getContentDisposition(s"${file.getName}"),
        CONTENT_TYPE -> "application/x-download"
      )
  }

}
